/*
PARI/GP scripts for digit-based functions 
=============================================================
File: DigitBasedFunctions.txt    
Link: https://oeis.org/wiki/File:DigitBasedFunctions.txt
=============================================================
*/

DigitsToNumber(d,b=10) = subst(Pol(d),'x,b);
/* ----------------------------------------------------------
  Converts a vector of digits d to a number, assuming base b.
  The base argument b is optional (default = 10).
  This function will become obsolete (replaced by intrinsic
  'fromdigits') though not yet in Version 2.7.1 of 16 May 2014.
---------------------------------------------------------- */

ReverseDigits(n,b=10) = subst(Polrev(digits(n,b)),'x,b);
/* ----------------------------------------------------------
  Reverses the base-b digits of a number n.
  The base argument b is optional (default = 10).
---------------------------------------------------------- */

IsReversedGE(n,b=10) = ReverseDigits(n,b) >= n;
/* ----------------------------------------------------------
  Boolean test: The number with reversed digits must be
  the greater (or equal) one of the pair.
  Examples: 32 returns 0, 23 returns 1, 22 returns 1.
---------------------------------------------------------- */

IsPalindrome(n,b=10) = n==ReverseDigits(n,b);
/* ----------------------------------------------------------
  Boolean test: The number with reversed digits must be
  the same as the original.
---------------------------------------------------------- */

NumberOfDigits(n,b=10) = #digits(n,b);
/* ----------------------------------------------------------
  Returns the number of digits of the integer n in base b.
  The base argument b is optional (default = 10).
---------------------------------------------------------- */

SumOfDigits(n,b=10) =
/* ----------------------------------------------------------
  Returns the sum of digits of the integer n in base b.
  The base argument b is optional (default = 10).
---------------------------------------------------------- */
{
  my (d = digits(n,b));
  sum(k=1,#d,d[k]);
}

ProductOfDigits(n,b=10) =
/* ----------------------------------------------------------
  Returns the product of digits of the integer n in base b.
  The base argument b is optional (default = 10).
---------------------------------------------------------- */
{
  my (d = digits(n,b));
  prod(k=1,#d,d[k]);
}

DigitsSumProduct(n,b=10) =
/* ----------------------------------------------------------
  Returns the product of digits, multiplied by the sum of
  digits of the nonn integer n in base b.
  The base argument b is optional (default = 10).
  See A066308.
---------------------------------------------------------- */
{
  my (d = digits(n,b));
  return (sum(k=1,#d,d[k])*prod(k=1,#d,d[k]));
}

DigitalRoot(n,b=10) = if(n,(n-1)%(b-1)+1,n);
/* ----------------------------------------------------------
  Returns the digital root of the nonn integer n in base b.
  The base argument b is optional (default = 10).
  See A010888.
---------------------------------------------------------- */


RTruncIsCoprime(n,b=10) = gcd(n,(n-n%b)\b)==1;
/* ----------------------------------------------------------
  Boolean: Tests if n is coprime to the number obtained
  by truncating off its rightmost digit in base b.
---------------------------------------------------------- */

RTruncIsNotCoprime(n,b=10) = !RTruncIsCoprime(n,b);
/* ----------------------------------------------------------
  Boolean: logical negation of RTruncIsCoprime(n,b=10).
---------------------------------------------------------- */


/*
=============================================================
   Functions related specifically to binary expansions
=============================================================
*/

Parity(n) = hammingweight(n)%2;
/* ----------------------------------------------------------
  Returns 1 when the sum of binary digits is odd
  and 0 when it is even.
---------------------------------------------------------- */

GrayCode(n) = bitxor(n,n>>1);
/* ----------------------------------------------------------
  Converts a non-negative integer to its Gray-code.
  The inverse of GrayDecode.
  Link: http://en.wikipedia.org/wiki/Gray_code 
---------------------------------------------------------- */

GrayDecode(g) =
/* ----------------------------------------------------------
  The inverse of GrayCode.
  Converts a Gray-code to the integer it is encoding.
  Link: http://en.wikipedia.org/wiki/Gray_code 
---------------------------------------------------------- */
{
  my(m = g>>1);
  while(m,g=bitxor(g,m);m=m>>1);
  return(g);
}


/*
=============================================================
   Contributed to OEIS Wiki by Stanislav Sykora
=============================================================
*/
